home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_se / run_feature_6.e < prev    next >
Text File  |  1998-12-22  |  8KB  |  341 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class RUN_FEATURE_6
  17.    
  18. inherit RUN_FEATURE redefine base_feature end;
  19.  
  20. creation make
  21.    
  22. feature 
  23.    
  24.    base_feature: ONCE_FUNCTION;
  25.       
  26.    arguments: FORMAL_ARG_LIST;
  27.  
  28.    result_type: TYPE;
  29.  
  30.    local_vars: LOCAL_VAR_LIST;
  31.    
  32.    routine_body: COMPOUND;
  33.  
  34.    rescue_compound: COMPOUND;
  35.  
  36. feature
  37.  
  38.    is_once_function: BOOLEAN is true;
  39.  
  40.    is_static: BOOLEAN is false;
  41.    
  42.    static_value_mem: INTEGER is 0;
  43.  
  44. feature
  45.  
  46.    afd_check is
  47.       do
  48.      routine_afd_check;
  49.       end;
  50.  
  51.    can_be_dropped: BOOLEAN is 
  52.       do
  53.      Result := is_pre_computable;
  54.       end;
  55.    
  56.    mapping_c is
  57.       do
  58.      if is_pre_computable then
  59.         cpp_once_result;        
  60.      else
  61.         default_mapping_function;
  62.      end;
  63.       end;
  64.    
  65.    c_define is
  66.       local
  67.      bfbc: BASE_CLASS;
  68.       do
  69.      bfbc := base_feature.base_class;
  70.      if is_pre_computable then
  71.         if not bfbc.once_flag(once_mark) then
  72.            once_variable;
  73.         end;
  74.         cpp.add_pre_computed_once_function(Current);
  75.      else
  76.         if not bfbc.once_flag(once_mark) then
  77.            once_boolean;
  78.            once_variable;
  79.         end;
  80.         define_prototype;
  81.         cpp.put_string("if(");
  82.         once_flag; 
  83.         cpp.put_string("==0){%N");
  84.         c_define_opening;
  85.         once_flag;
  86.         cpp.put_string("=1;%N");
  87.         if routine_body /= Void then
  88.            routine_body.compile_to_c;
  89.         end;
  90.         c_define_closing;
  91.         cpp.put_string("}%N");
  92.         cpp.put_string("return ");
  93.         cpp_once_result;
  94.         cpp.put_string(";}%N");
  95.         c_frame_descriptor;
  96.      end;
  97.       end;
  98.    
  99. feature {NONE}   
  100.  
  101.    is_pre_computable: BOOLEAN is
  102.       do
  103.      if frozen_general.fast_has(name.to_string) then
  104.         Result := true;
  105.      elseif arguments = Void and then not use_current then 
  106.         if routine_body = Void then
  107.            Result := true;
  108.         elseif not run_control.invariant_check then
  109.            Result := routine_body.is_pre_computable;
  110.         end;
  111.      end;
  112.      if Result then
  113.         if require_assertion /= Void then
  114.            require_assertion.clear_run_feature;
  115.         end;
  116.         if ensure_assertion /= Void then
  117.            ensure_assertion.clear_run_feature;
  118.         end;
  119.      end;
  120.       end;
  121.  
  122. feature {ABSTRACT_RESULT}
  123.  
  124.    cpp_once_result is
  125.      -- Produce the C name of the once Result.
  126.       do
  127.      c_code.clear;
  128.      once_result_in(c_code);
  129.      cpp.put_string(c_code);
  130.       end;
  131.    
  132.    once_variable is
  133.       do
  134.      c_code.clear;
  135.      c_code.extend('T');
  136.      if result_type.is_expanded then
  137.         result_type.id.append_in(c_code);
  138.         c_code.extend(' ');
  139.      else
  140.         c_code.extend('0');
  141.         c_code.extend('*');
  142.      end;
  143.      once_result_in(c_code);
  144.      c_code2.clear;
  145.      result_type.c_initialize_in(c_code2);
  146.      cpp.put_extern5(c_code,c_code2);
  147.       end;
  148.  
  149. feature {CALL_PROC_CALL}
  150.  
  151.    collect_c_tmp is
  152.       do
  153.       end;
  154.  
  155. feature {ADDRESS_OF_POOL}
  156.  
  157.    address_of_c_define(caller: ADDRESS_OF) is
  158.       do
  159.      if run_control.boost then
  160.         if use_current then
  161.         else
  162.            address_of_c_define_wrapper(caller);
  163.         end;
  164.      else
  165.         address_of_c_define_wrapper(caller);
  166.      end;
  167.       end;
  168.  
  169. feature {ADDRESS_OF}
  170.    
  171.    address_of_c_mapping is
  172.       do
  173.      if run_control.boost then
  174.         if use_current then
  175.            mapping_name;
  176.         else
  177.            address_of_c_mapping_wrapper;
  178.         end;
  179.      else
  180.         address_of_c_mapping_wrapper;
  181.      end;
  182.       end;
  183.  
  184. feature {NONE}
  185.    
  186.    initialize is
  187.       do
  188.      result_type := base_feature.result_type;
  189.      arguments := base_feature.arguments;
  190.      if result_type.is_anchored then
  191.         fe_vffd7;
  192.      elseif result_type.is_formal_generic then
  193.         eh.add_position(result_type.start_position);
  194.         fatal_error("Result type of a once function must %
  195.             %not be a formal generic argument (VFFD.7).");
  196.      end;
  197.      result_type := result_type.to_runnable(current_type);
  198.      if arguments /= Void then
  199.         if not arguments.is_runnable(current_type) then
  200.            !!arguments.with(arguments,current_type);
  201.         end;
  202.      end;
  203.      local_vars := base_feature.local_vars;
  204.      if local_vars /= Void then
  205.         local_vars := local_vars.to_runnable(current_type);
  206.      end;
  207.      routine_body := base_feature.routine_body;
  208.      if routine_body /= Void then
  209.         routine_body := routine_body.to_runnable(current_type);
  210.      end;
  211.      if run_control.require_check then
  212.         require_assertion := base_feature.run_require(Current);
  213.      end;
  214.      if run_control.ensure_check then
  215.         ensure_assertion := base_feature.run_ensure(Current);
  216.      end;
  217.      rescue_compound := base_feature.rescue_compound;
  218.      if rescue_compound /= Void then
  219.         exceptions_handler.set_used;
  220.         rescue_compound := rescue_compound.to_runnable(current_type);
  221.      end;
  222.      once_routine_pool.add_function(Current);
  223.       end;
  224.    
  225.    compute_use_current is
  226.       do
  227.      std_compute_use_current;
  228.       end;
  229.    
  230. feature {NONE}
  231.    
  232.    frozen_general: ARRAY[STRING] is
  233.       once
  234.      Result := <<us_std_error, us_std_input, us_io, us_std_output>>;
  235.       end;
  236.    
  237. feature {C_PRETTY_PRINTER}
  238.    
  239.    c_pre_computing is
  240.       require
  241.      is_pre_computable;
  242.      cpp.on_c;
  243.       local
  244.      bfbc: BASE_CLASS;
  245.       do
  246.      bfbc := base_feature.base_class;
  247.      echo.put_character('%T');
  248.      echo.put_string(bfbc.name.to_string);
  249.      echo.put_character('.');
  250.      echo.put_string(name.to_string);
  251.      echo.put_character('%N');
  252.      if run_control.require_check then
  253.         if require_assertion /= Void then
  254.            require_assertion.compile_to_c;
  255.         end;
  256.      end;
  257.      cpp_once_result;
  258.      cpp.put_character('=');
  259.      result_type.c_initialize;
  260.      cpp.put_string(fz_00);
  261.      if local_vars /= Void then
  262.         cpp.put_character('{');
  263.         local_vars.c_declare;
  264.      end;
  265.      if routine_body /= Void then
  266.         routine_body.compile_to_c; 
  267.      end;
  268.      if run_control.ensure_check then
  269.         if ensure_assertion /= Void then
  270.            ensure_assertion.compile_to_c;
  271.         end;
  272.      end;
  273.      if local_vars /= Void then
  274.         cpp.put_character('}');
  275.      end;
  276.      cpp.put_string("/*PCO*/%N");
  277.       end;
  278.  
  279.    tmp_string: STRING is
  280.       once
  281.      !!Result.make(10);
  282.       end;
  283.  
  284. feature {RUN_CLASS}
  285.  
  286.    jvm_field_or_method is
  287.       do
  288.      jvm.add_method(Current);
  289.       end;
  290.  
  291. feature
  292.  
  293.    mapping_jvm is
  294.       do
  295.      routine_mapping_jvm;
  296.       end;
  297.  
  298. feature {JVM}
  299.  
  300.    jvm_define is
  301.       local
  302.      result_space, branch, idx_flag, idx_result: INTEGER;
  303.       do
  304.      idx_result := once_routine_pool.idx_fieldref_for_result(Current);
  305.      idx_flag := once_routine_pool.idx_fieldref_for_flag(Current);
  306.      result_space := result_type.jvm_stack_space;
  307.      method_info_start;
  308.      code_attribute.opcode_getstatic(idx_flag,1);
  309.      branch := code_attribute.opcode_ifne;
  310.      code_attribute.opcode_iconst_1;
  311.      code_attribute.opcode_putstatic(idx_flag,-1);
  312.      jvm_define_opening;
  313.      if routine_body /= Void then
  314.         routine_body.compile_to_jvm;
  315.      end;
  316.      jvm_define_closing;
  317.      code_attribute.opcode_putstatic(idx_result,- result_space);
  318.      code_attribute.resolve_u2_branch(branch);
  319.      code_attribute.opcode_getstatic(idx_result,result_space);
  320.      result_type.run_type.jvm_return_code;
  321.      method_info.finish;
  322.       end;
  323.    
  324. feature {NONE}
  325.  
  326.    update_tmp_jvm_descriptor is
  327.       do
  328.      routine_update_tmp_jvm_descriptor;
  329.       end;
  330.  
  331. feature {ONCE_RESULT}
  332.  
  333.    fe_vffd7 is
  334.       do
  335.      eh.add_position(result_type.start_position);
  336.      fatal_error("Result type of a once function must %
  337.              %not be anchored (VFFD.7).");
  338.       end;
  339.  
  340. end -- RUN_FEATURE_6
  341.